//
//  JigSawMetaView.m
//  JigSawKiosk
//
//  Created by Stulberg on 10-10-17.
//  Copyright 2010 FruitonLabs. All rights reserved.
//


#import "JigSawMetaView.h"

#import "JigSawFullScreenMovieView.h"

#import "JigSawBackgroundFrameView.h"

#import "JigSawMainMovieView.h"

#import "JigSawButtonContainerView.h"

#import "JigSawFeedbackView.h"

#import "ArduinoCom.h"

#import "DIVARequest.h"

#import "InitializationEmailSender.h"

//#import "defines.h"

// Global vars
extern int kUseDIVA ;
extern int kRotate ;
extern int kDefaultMode ;
extern int kFeedbackMode ;
extern int kIntroMode ;
extern int kMovieMode ;
extern int kFullScreen ;
extern int kRecordTime ;
extern int kUseInactivityTimer ;
extern float kInactivityDuration ;

// Paths
extern NSString* kGraphicsPath ;
extern NSString* kMoviePath ;


// graphics
extern NSString* kPlayBackBackgroundImage ;
extern NSString* kFeedBackBackgroundImage ;
extern NSString* kMouseImage ;
extern NSString* kHotkeysImage ;
extern NSString* kWatchSelectedImage ;
extern NSString* kRecordGreenImage ;
extern NSString* kWatchUnselectedImage ;
extern NSString* kRecordRedImage ;
extern NSString* kMovieRecordPath ;

// Movies
extern NSString* kDefaultMovieName ;
extern NSString* kIntroMovieName ;
extern int kNumberOfMovies ;
extern NSString* kPreview1MovieName ;
extern NSString* kPreview2MovieName ;
extern NSString* kPreview3MovieName ;
extern NSString* kPreview4MovieName ;
extern NSString* kPreview5MovieName ;
extern NSString* kPreview6MovieName ;
extern NSString* kPreview7MovieName ;
extern NSString* kPreview8MovieName ;
extern NSString* kPreview9MovieName ;

extern NSString* kMovie1Name ;
extern NSString* kMovie2Name ;
extern NSString* kMovie3Name ;
extern NSString* kMovie4Name ;
extern NSString* kMovie5Name ;
extern NSString* kMovie6Name ;
extern NSString* kMovie7Name ;
extern NSString* kMovie8Name ;
extern NSString* kMovie9Name ;

extern float kPreviewStopOpacity ;

// DIVA
extern float kDIVAtimeout ;

extern NSString* kDIVAip ;
extern NSString* kDIVAport ;
extern NSString* kDIVAusername ;
extern NSString* kDIVApassword ;
extern NSString* kDIVApresent ;
extern NSString* kDIVAabsent ;

// Arduino
extern int kUseArduino ;
extern NSString *kArduinoPort ;
extern int kArduinoBaudRate ;

// Email
extern NSString* kEmailSMTP ;
extern int kEmailPort ;
extern NSString* kEmailFromAddress ;
extern NSString* kEmailFromName ;
extern NSString* kEmailFromPassword ;
extern NSString* kEmailFeedbackEmailSubject ;
extern NSString* kEmailFeedbackEmailHTMLFilepath ;
extern NSString* kEmailFeedbackEmailHTMLImageDir ;
extern NSString* kEmailFeedbackEmailTxtFilepath ;
extern NSString* kEmailDefaultMessage ;
extern NSString* kStartupEmailToAddress ;
extern NSString* kStartupEmailSubject ;
extern NSString* kStartupEmailMessage ;


@interface JigSawMetaView (internal)
- (CGPoint) mapMouse:(CGPoint) inPoint inRect:(CGRect) inRect ;
- (CGPoint) reMap:(CGPoint)inPoint inRect:(CGRect)inRect ;
@end


@implementation JigSawMetaView

@synthesize fsMovieView, backgroundFrame, mainMovieView, buttonContainer, feedbackView, dvr, arduino ;
@synthesize aMouse ;

- (void) dealloc {
	[fsMovieView release] ;
	[backgroundFrame release] ;
	//[topFrame release] ;
	[mainMovieView release] ;
	[buttonContainer release] ;
	//[bottomFrame release] ;
	[feedbackView release] ;	
	[movieNameArray release] ;
	[aMouse release] ;
	[super dealloc] ;
	
}


- (void) awakeFromNib {
	
	[self populateConfiguration];
	
	[self setWantsLayer:YES] ;
	[[self window] setAcceptsMouseMovedEvents:YES];
	[NSCursor hide];
	
	//send an email to JigsawKiosk owner that application has started
	InitializationEmailSender *initializationEmail = [[InitializationEmailSender alloc] init];
	[initializationEmail sendEmailMessageTo:@"Jigsaw Kiosk Owner" AtEmail:kStartupEmailToAddress];
	[initializationEmail release];

	//if (kFullScreen == 0) 
	
		[[self window] makeFirstResponder:self] ; 
	
	if(kUseDIVA == 1) {
		dvr = [[[DIVARequest alloc] init] autorelease] ;
		[dvr setDelegate:self] ;
	}
	
	if (kUseArduino == 1) {
		arduino = [[ArduinoCom alloc] init] ;
		[arduino setDelegate:self] ;
	}
	
	currentKioskMode =  kDefaultMode; //kDefaultMode kIntroMode kMovieMode kFeedbackMode

	if (kFullScreen == 1) {
		[self toggleFullScreen] ;
	}
	[self getMovieLocators] ;
	
	[self setupViews] ;

	
	if(kRotate) {
		[fsMovieView setFrameCenterRotation:-90.0f];
		[backgroundFrame setFrameCenterRotation:-90.0f];
		[mainMovieView setFrameCenterRotation:-90.0f];
		[buttonContainer setFrameCenterRotation:-90.0f];
		[feedbackView setFrameCenterRotation:-90.0f];
		[aMouse setFrameCenterRotation:-90.0f] ;
		[self needsDisplay] ;

	}
}

#pragma mark Setup views
-(void) setupViews {
	NSRect aRect ;
	
	// BACKGROUND  FRAME
	NSString *Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kPlayBackBackgroundImage];
	NSURL *url   = [NSURL fileURLWithPath:Lpath];
	
	if(kRotate) 
		aRect = NSMakeRect([self bounds].size.width/4.5714, -[self bounds].size.height/2.571428571428571,  [self bounds].size.height, [self bounds].size.width) ;
	else
		aRect = NSMakeRect(0, 0, [self bounds].size.width, [self bounds].size.height) ;
		
	backgroundFrame = [[JigSawBackgroundFrameView alloc] initWithImage:aRect name:url] ;
	[self addSubview:backgroundFrame] ;

	
	// MAIN MOVIE VIEW
	
	if(kRotate) {
		float mWidth = [self bounds].size.height ;
		float mHeight = (mWidth*9)/16 ;
		aRect = NSMakeRect([self bounds].size.width*0.338, [self bounds].size.height*0.2188, 
						   mWidth, mHeight) ;
		//NSLog(@" height = %f, width = %f", [self bounds].size.height, [self bounds].size.width) ;
	}
		else {
		float mWidth = [self bounds].size.width ;
		float mHeight = (mWidth*9)/16 ;
		aRect = NSMakeRect(0, [self bounds].size.height*0.46, mWidth, mHeight) ;
	}
	mainMovieView = [[JigSawMainMovieView alloc] initWithFrame:aRect] ;
	[mainMovieView startMovieWithCallbackOnComplete:introMovieURL] ;
	// add mainMoview to view
	[mainMovieView movieStop] ;
	[self addSubview:mainMovieView] ;
	[mainMovieView setDelegate:self] ;
	if(currentKioskMode != kIntroMode && currentKioskMode != kMovieMode) [mainMovieView setHidden:YES]; 
	
	
	// BUTTON CONTAINER
	
	if(kRotate) {
		aRect = NSMakeRect([self bounds].size.width*0.05, [self bounds].size.height*0.3861, // [self bounds].size.height*0.3							// x, y pos
						    [self bounds].size.height, [self bounds].size.width*0.128) ; // width, height
	}
	else {
		aRect = NSMakeRect(0, [self bounds].size.height*0.3,							// x, y pos
						   [self bounds].size.width, [self bounds].size.height*0.128) ; // width, height
	}
	
	buttonContainer = [[JigSawButtonContainerView alloc] initWithURLS:aRect urls:previewURLArray] ;
	[self addSubview:buttonContainer] ;
	[buttonContainer setDelegate:self] ; 
	[buttonContainer stopAllPreviews] ;
	if(currentKioskMode != kIntroMode && currentKioskMode != kMovieMode) [buttonContainer setHidden:YES]; 
	
	
	// FEEDBACK FORM
	if(kRotate) {
		aRect = NSMakeRect([self bounds].size.width*0.2103, [self bounds].size.height*0.0143, 
						   [self bounds].size.height, [self bounds].size.width*0.547) ; // width, height
	}
	else {
		aRect = NSMakeRect(0, [self bounds].size.height*0.218, 
						   [self bounds].size.width, [self bounds].size.height*0.547) ;
		}
	feedbackView = [[JigSawFeedbackView alloc] initWithFrame:aRect] ;
	[self addSubview:feedbackView] ;
	[feedbackView setDelegate:self] ;
	
	if(currentKioskMode != kFeedbackMode) [feedbackView setHidden:YES] ;
	
	
	// DEFAULT VIEW
	Lpath = [NSString stringWithFormat:@"%@%@", kMoviePath, kDefaultMovieName];
	url   = [NSURL fileURLWithPath:Lpath];
	
	if(kRotate) 
		aRect = NSMakeRect([self bounds].size.width/4.5714, -[self bounds].size.height/2.571428571428571, [self bounds].size.height, [self bounds].size.width) ;
	else
		aRect = NSMakeRect(0, 0, [self bounds].size.width, [self bounds].size.height) ;
	

	fsMovieView = [[JigSawFullScreenMovieView alloc] initWithMovie:aRect movie:url] ;
	[self addSubview:fsMovieView] ;
	if(currentKioskMode != kDefaultMode) [fsMovieView setHidden:YES] ;
	
	
	Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kMouseImage];
	url   = [NSURL fileURLWithPath:Lpath];
	

	float mWidth = [self bounds].size.height*0.05 ;
	float mHeight = (mWidth*9)/16 ;
	
	aRect = NSMakeRect(0, 0, mHeight, mWidth) ;
	aMouse = [[JigSawMouseView alloc] initWithImage:aRect name:url] ;
	[self addSubview:aMouse] ;	
}


#pragma mark File location
-(void) getMovieLocators {

	NSString *path = kMoviePath;
	
	movieNameArray = [[NSMutableArray alloc] init];
	NSMutableArray *previewNameArray = [[[NSMutableArray alloc] init] autorelease];
	
	movieURLArray = [[NSMutableArray alloc] init];
	previewURLArray = [[NSMutableArray alloc] init];
	
	
	// these are to be read from the config file.... one day
	if(kNumberOfMovies >= 1)[previewNameArray addObject:kPreview1MovieName] ;
	if(kNumberOfMovies >= 2)[previewNameArray addObject:kPreview2MovieName] ;
	if(kNumberOfMovies >= 3)[previewNameArray addObject:kPreview3MovieName] ;
	if(kNumberOfMovies >= 4)[previewNameArray addObject:kPreview4MovieName] ;
	if(kNumberOfMovies >= 5)[previewNameArray addObject:kPreview5MovieName] ;
	if(kNumberOfMovies >= 6)[previewNameArray addObject:kPreview6MovieName] ;
	if(kNumberOfMovies >= 7)[previewNameArray addObject:kPreview7MovieName] ;
	if(kNumberOfMovies >= 8)[previewNameArray addObject:kPreview8MovieName] ;
	if(kNumberOfMovies == 9)[previewNameArray addObject:kPreview9MovieName] ;
	
	if(kNumberOfMovies >= 1)[movieNameArray addObject:kMovie1Name] ;
	if(kNumberOfMovies >= 2)[movieNameArray addObject:kMovie2Name] ;
	if(kNumberOfMovies >= 3)[movieNameArray addObject:kMovie3Name] ;
	if(kNumberOfMovies >= 4)[movieNameArray addObject:kMovie4Name] ;
	if(kNumberOfMovies >= 5)[movieNameArray addObject:kMovie5Name] ;
	if(kNumberOfMovies >= 6)[movieNameArray addObject:kMovie6Name] ;
	if(kNumberOfMovies >= 7)[movieNameArray addObject:kMovie7Name] ;
	if(kNumberOfMovies >= 8)[movieNameArray addObject:kMovie8Name] ;
	if(kNumberOfMovies == 9)[movieNameArray addObject:kMovie9Name] ;
	
	NSString *Lpath ;
	
	for(NSString *name in movieNameArray) {
		Lpath = [NSString stringWithFormat:@"%@%@", path, name];
		NSURL *url   = [NSURL fileURLWithPath:Lpath];
		//if(kDebug) NSLog(@"movie names = %@", Lpath) ;
		[movieURLArray addObject:url] ;
	}
	
	for(NSString *name in previewNameArray) {
		Lpath = [NSString stringWithFormat:@"%@%@", path, name];
		NSURL *url   = [NSURL fileURLWithPath:Lpath];
		//if(kDebug) NSLog(@"Preview names = %@", Lpath) ;
		[previewURLArray addObject:url] ;
	}
	
	Lpath = [NSString stringWithFormat:@"%@%@", path, kIntroMovieName];
	introMovieURL = [[[NSURL alloc] initFileURLWithPath:Lpath] retain] ;
	//if(kDebug) NSLog(@"introMovieURL: %@", introMovieURL);
}

#pragma mark Callbacks (game logic)
// callbacks


// goto main movie view
- (void) arduinoPresentCallback:(ArduinoCom *)myArduinoRequest {
	printf("arduinoPresentCallback response\n");
	[self resetInactivityTimer] ;
	
	if (currentKioskMode == kDefaultMode) {
		//[[fsMovieView flMovie] stop] ;
		//[[fsMovieView flMovie] gotoBeginning] ;
		[fsMovieView disapear:0.75] ;
		[self startTransitionTimer:0.5] ;
	}
	
}
// goto main screen saver default
- (void) arduinoAbsentCallback:(ArduinoCom *)myArduinoRequest {
	printf("arduinoAbsentCallback response\n");
	
	[self switchView:mainMovieView previous:feedbackView] ;
	NSString* Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kPlayBackBackgroundImage];
	NSURL *url   = [NSURL fileURLWithPath:Lpath];
	[backgroundFrame swapImage:url] ;
	
	[buttonContainer startStopPreviewsAtStrip] ;
	[buttonContainer stopAllPreviews] ;
	
	[mainMovieView setHidden:YES] ;
	[feedbackView setHidden:YES] ;
	[buttonContainer setHidden:YES];
	
	[[self window] makeFirstResponder:self] ;
	
	currentKioskMode = kDefaultMode ;

	currentKioskMode = kDefaultMode ;
	[fsMovieView reapear:2.75] ;
	
	[fsMovieView setHidden:NO] ;
	[mainMovieView setHidden:YES] ;
	[buttonContainer setHidden:YES] ;
	[feedbackView setHidden:YES] ;
}

// DIVA CALLBACK
// goto main movie view
- (void) divaPresentCallback:(DIVARequest *)myDIVARequest {
	//if(kDebug)
	printf("DIVA REQUEST PRESENT\n");
	[self resetInactivityTimer] ;
	
	if (currentKioskMode == kDefaultMode) {
		//[[fsMovieView flMovie] stop] ;
		//[[fsMovieView flMovie] gotoBeginning] ;
		[fsMovieView disapear:0.75] ;
		[self startTransitionTimer:0.5] ;
	}
}

// goto main screen saver default
- (void) divaAbsentCallback:(DIVARequest *)myDIVARequest {
	//if(kDebug)
		printf("DIVA REQUEST ABSENT\n");
	
	//if (currentKioskMode == kFeedbackMode) {
		//currentKioskMode = kIntroMode ;
		[self switchView:mainMovieView previous:feedbackView] ;
		NSString* Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kPlayBackBackgroundImage];
		NSURL *url   = [NSURL fileURLWithPath:Lpath];
		[backgroundFrame swapImage:url] ;
		
		//[mainMovieView startMovieWithCallbackOnComplete:introMovieURL] ;
		//[mainMovieView movieStart] ;
		[buttonContainer startStopPreviewsAtStrip] ;
		[buttonContainer stopAllPreviews] ;
	
		[mainMovieView setHidden:YES] ;
		[feedbackView setHidden:YES] ;
		[buttonContainer setHidden:YES];
		
		[[self window] makeFirstResponder:self] ;
		
		currentKioskMode = kDefaultMode ;
		
	//}
	//else{
		currentKioskMode = kDefaultMode ;
		//[[fsMovieView flMovie] gotoBeginning] ;
		//[[fsMovieView flMovie] play] ;
		[fsMovieView reapear:2.75] ;
		
		[fsMovieView setHidden:NO] ;
		[mainMovieView setHidden:YES] ;
		[buttonContainer setHidden:YES] ;
		[feedbackView setHidden:YES] ;
		
	//}
}

// play selected movie
- (void)buttonContainerCallback:(JigSawButtonContainerView *)myJigSawButtonContainerView buttonNumber:(int) buttonNumber {
	//if(kDebug) printf("\n Got callback from button container with button number %d\n", buttonNumber);
	
	[self resetInactivityTimer] ;
	//
	// goto movie view with movie at index
	//
	if (currentKioskMode != kMovieMode && currentKioskMode != kFeedbackMode) {		
		if (buttonNumber <= [movieURLArray count]) {
			
			[self stopInactivityTimer] ;
			
			currentKioskMode = kMovieMode ;
			[mainMovieView startMovieWithCallbackOnComplete:[movieURLArray objectAtIndex:buttonNumber]] ; // start movie
			feedbackView.currentMovieName = (NSString*) [movieNameArray objectAtIndex:buttonNumber] ; // update movie name
			
			[mainMovieView movieStart] ;
		}
	}
}

// goto feedback
- (void)mainMovieViewCallback:(JigSawMainMovieView *)myJigSawMainMovieView {
	//if(kDebug) printf("\n Got callback from main movie view movie complete \n");
	
	[self resetInactivityTimer] ;
	
	// From movie to intro feedback
	
	if (currentKioskMode == kMovieMode) {
		
		[self switchView:feedbackView previous:mainMovieView] ;
		NSString* Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kFeedBackBackgroundImage];
		NSURL *url   = [NSURL fileURLWithPath:Lpath];
		
		[mainMovieView movieStop] ;
		[mainMovieView startMovieWithCallbackOnComplete:introMovieURL] ;
		
		[backgroundFrame swapImage:url] ;
		
		[feedbackView setHidden:NO] ;
		[feedbackView startRecordPreview] ;
		
		[mainMovieView setHidden:YES] ;
		[buttonContainer setHidden:YES];
		
		currentKioskMode = kFeedbackMode ;
	}
}

// goto intro mode
- (void)feedBackCallback:(JigSawFeedbackView *)myJigSawFeedbackView {
	//if(kDebug) printf("\n Got callback from feedback view\n");
	
	
	[self switchView:mainMovieView previous:feedbackView] ;
	NSString* Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kPlayBackBackgroundImage];
	NSURL *url   = [NSURL fileURLWithPath:Lpath];
	[backgroundFrame swapImage:url] ;
		
	//[mainMovieView startMovieWithCallbackOnComplete:introMovieURL] ;
	[mainMovieView movieStart] ;
	[buttonContainer startStopPreviewsAtStrip] ;
	[buttonContainer setIsDisabled:FALSE] ;
	
	[mainMovieView setHidden:NO] ;
	[feedbackView setHidden:YES] ;
	[feedbackView stopRecordPreview] ;
	
	[buttonContainer setHidden:NO];
	
	[[self window] makeFirstResponder:self] ;
	
	currentKioskMode = kIntroMode ;
}


-(void) transitionTimerMethod:(NSTimer *)timer {
	
	// From default to intro mode
	if (currentKioskMode == kDefaultMode) {
		
		NSString* Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kPlayBackBackgroundImage];
		NSURL *url   = [NSURL fileURLWithPath:Lpath];
		[backgroundFrame swapImage:url] ;
		
		
		[buttonContainer startStopPreviewsAtStrip] ;
		[buttonContainer setIsDisabled:FALSE] ;
		
		[mainMovieView startMovieWithCallbackOnComplete:introMovieURL] ;
		[mainMovieView movieStart] ;
		
		[[fsMovieView flMovie] stop] ;
		
		[fsMovieView setHidden:YES] ;
		[mainMovieView setHidden:NO] ;
		[buttonContainer setHidden:NO] ;
		
		[self resetInactivityTimer] ;
		
		[[self window] makeFirstResponder:self] ;
		
		currentKioskMode = kIntroMode ;

	}
}

-(void) startTransitionTimer:(float) withDuration {
	if ([transitionTimer isValid]) {
		[transitionTimer invalidate] ;
		transitionTimer = nil ;
		[transitionTimer release] ;
	}
	transitionTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:withDuration]
										   interval:0.1	 
											 target: self
										   selector: @selector(transitionTimerMethod:)
										   userInfo: nil
											repeats: NO];
	[[NSRunLoop currentRunLoop] addTimer:transitionTimer forMode:NSDefaultRunLoopMode];
}

#pragma mark Mouse and Key Event

- (CGPoint) mapMouse:(CGPoint)inPoint inRect:(CGRect)inRect {
	CGPoint mapped ;
	
	// (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min 
	// for CCW
	mapped.y = (inPoint.x - inRect.origin.x) * (inRect.origin.y - inRect.size.height) / (inRect.size.width - inRect.origin.x) + inRect.size.height ;
	
	mapped.x = (inPoint.y - inRect.origin.y) * (inRect.size.width - inRect.origin.x) / (inRect.size.height - inRect.origin.y) + inRect.origin.x ;

	return mapped ;
}


- (void)mouseDown:(NSEvent *)event
{
	//NSPoint  loc = [self convertPoint: [event locationInWindow] fromView: nil];	
	//CGPoint cgloc = NSPointToCGPoint(loc) ;
	// goto intro view
	//

	[self resetInactivityTimer] ;
	
	if (currentKioskMode == kDefaultMode) {
		//currentKioskMode = kIntroMode ;
		[fsMovieView disapear:0.75] ;
		[self startTransitionTimer:0.5] ;
	}
	
	//if(kRotate) {
		if(currentKioskMode == kFeedbackMode) {
			NSPoint mLoc = NSPointFromCGPoint([aMouse rootLayer].position) ;
			NSPoint convertedPoint = [self convertPoint:mLoc toView:feedbackView];
			convertedPoint.y += [[aMouse rootLayer] bounds].size.height/2 ;
			[feedbackView mouseIn:convertedPoint] ;
		}
		
		if(currentKioskMode == kIntroMode || currentKioskMode == kMovieMode) {
			NSPoint mLoc = NSPointFromCGPoint([aMouse rootLayer].position) ;
			NSPoint convertedPoint = [self convertPoint:mLoc toView:buttonContainer];
			convertedPoint.y += [[aMouse rootLayer] bounds].size.height/2 ;
			CGPoint cgloc = NSPointToCGPoint(convertedPoint) ;
			[buttonContainer mouseIn:cgloc] ;
		}
	//}
}

- (void)mouseMoved:(NSEvent *)event {
	//if (kRotate) {
		NSPoint  loc = [self convertPoint: [event locationInWindow] fromView: nil];	
		CGPoint cgloc = NSPointToCGPoint(loc) ;
		
		if (kRotate) {
			CGRect aRect = NSRectToCGRect([self bounds]) ;
			mouseLocation = [self mapMouse:cgloc inRect:aRect] ;
		}
	else {
		mouseLocation = cgloc ;
	}

		
		[CATransaction begin];
		[CATransaction setValue:(id)kCFBooleanTrue
						 forKey:kCATransactionDisableActions];
		[[aMouse rootLayer] setPosition:mouseLocation] ;
		[CATransaction commit];
		
		
		[self displayIfNeeded];
	//}
}

- (void) keyUp: (NSEvent *) event
{
	
    NSString *characters;
    characters = [event characters];
	
    unichar character;
    character = [characters characterAtIndex: 0];
	
	//if(kDebug) printf("\n Received key down = %d\n", character);
	
	[self resetInactivityTimer] ;
	
	if (currentKioskMode == kDefaultMode) {
		//currentKioskMode = kIntroMode ;
		[fsMovieView disapear:0.75] ;
		[self startTransitionTimer:0.5] ;
	}
	
	// s or S
	if (character == 115 || character == 83) {
		
		if (currentKioskMode == kFeedbackMode) {
			if (![feedbackView isEditing]) {
				[feedbackView toggleRecord] ;
			}
		}
		
		if (currentKioskMode == kMovieMode) {
			currentKioskMode = kFeedbackMode ;
			[self switchView:feedbackView previous:mainMovieView] ;
			NSString* Lpath = [NSString stringWithFormat:@"%@%@", kGraphicsPath, kFeedBackBackgroundImage];
			NSURL *url   = [NSURL fileURLWithPath:Lpath];
			
			[mainMovieView movieStop] ;
			[mainMovieView startMovieWithCallbackOnComplete:introMovieURL] ;
			
			[backgroundFrame swapImage:url] ;
			
			[feedbackView setHidden:NO] ;
			[feedbackView startRecordPreview] ;
			[mainMovieView setHidden:YES] ;
			[buttonContainer setHidden:YES];

		}
	}
	
	// enter
	if (character == 13) {
		if (currentKioskMode == kFeedbackMode) {
			if (![feedbackView isEditing]) {
				if ([feedbackView isCommenting]) {
					[self switchView:mainMovieView previous:feedbackView] ;
					[feedbackView startFinishTimer] ;
				}
			}
		}
	}

	
	// r or R
	if (character == 114 || character == 82) {
		if (currentKioskMode == kFeedbackMode) {
			if (![feedbackView isEditing]) {
				
				// uncomment to enable r to toggle recording in feedback mode
				//[feedbackView toggleRecord] ; 
			}
		}
	}
	
	// a or A
	if (character == 97 || character == 65 ) {
		if (![feedbackView isEditing]) {
			
			if (currentKioskMode == kFeedbackMode) {
				//currentKioskMode = kIntroMode ;
				[self switchView:mainMovieView previous:feedbackView] ;
				[feedbackView startFinishTimer] ;
			}
		}
	}
	
	// 1
	if (character == 49) {
		if (currentKioskMode == kIntroMode) {
			int val = 0+(3*[buttonContainer getSelectedStrip]) ;
			if(val < kNumberOfMovies) {
				currentKioskMode = kMovieMode ;
				[self stopInactivityTimer] ;
				
				feedbackView.currentMovieName = (NSString*) [movieNameArray objectAtIndex:val] ; // update movie name
				[mainMovieView startMovieWithCallbackOnComplete:[movieURLArray objectAtIndex:val]] ;
				[buttonContainer stopAllPreviews] ;
				[mainMovieView movieStart] ;
			}
		}
	}
	
	// 2
	if (character == 50) {
		if (currentKioskMode == kIntroMode) {
			int val = 1+(3*[buttonContainer getSelectedStrip]) ;
			if(val < kNumberOfMovies) {
				currentKioskMode = kMovieMode ;
				[self stopInactivityTimer] ;
				
				feedbackView.currentMovieName = (NSString*) [movieNameArray objectAtIndex:val] ; // update movie name
				[mainMovieView startMovieWithCallbackOnComplete:[movieURLArray objectAtIndex:val]] ;
				[buttonContainer stopAllPreviews] ;
				[mainMovieView movieStart] ;
			}
		}
	}
	
	// 3
	if (character == 51) {
		if (currentKioskMode == kIntroMode) {
			int val = 2+(3*[buttonContainer getSelectedStrip]) ;
			if(val < kNumberOfMovies) {
				currentKioskMode = kMovieMode ;
				[self stopInactivityTimer] ;
				
				feedbackView.currentMovieName = (NSString*) [movieNameArray objectAtIndex:val] ; // update movie name
				[mainMovieView startMovieWithCallbackOnComplete:[movieURLArray objectAtIndex:val]] ;
				[buttonContainer stopAllPreviews] ;
				[mainMovieView movieStart] ;
			}
		}
	}
}

#pragma mark Inactivity Timer

-(void) inactivityTimerMethod:(NSTimer*)timer {
	//if(kDebug) printf("Intactivity timer fired");
	
	[[self window] makeFirstResponder:self] ;
	if(currentKioskMode != kFeedbackMode) {
		[mainMovieView movieStop] ;
		[buttonContainer stopAllPreviews] ;
		[fsMovieView reapear:2.75] ;
		[fsMovieView setHidden:NO] ;
		[mainMovieView setHidden:YES] ;
		[buttonContainer setHidden:YES] ;
		[feedbackView setHidden:YES] ;
		
		currentKioskMode = kDefaultMode ;
	}
}

-(void) resetInactivityTimer {
	if (inactivityTimer) {
		if ([inactivityTimer isValid]) {
			[inactivityTimer invalidate] ;
		}
		
		inactivityTimer = nil ;
		[inactivityTimer release] ;
	}
	if(kUseInactivityTimer == 1) {
		inactivityTimer =  [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:kInactivityDuration]
													interval:0.1	 
													  target: self
													selector: @selector(inactivityTimerMethod:)
													userInfo: nil
													 repeats: NO];
		[[NSRunLoop currentRunLoop] addTimer:inactivityTimer forMode:NSDefaultRunLoopMode];
	}
}

-(void) stopInactivityTimer {
	if ([inactivityTimer isValid]) {
		[inactivityTimer invalidate] ;
		inactivityTimer = nil ;
		[inactivityTimer release] ;
	}
}

#pragma mark View switching
-(void) switchView:(NSView*)view previous:(NSView*)previousView  {
	
	// Using an animation grouping because we may be changing the duration
	[NSAnimationContext beginGrouping];
	
	[[NSAnimationContext currentContext] setDuration:0.1];	
	//[[[self window] animator] setAlphaValue:0.01];
	[[self animator] replaceSubview:previousView with:view];

	[NSAnimationContext endGrouping];
	//[self setNeedsDisplay:YES] ;
	[aMouse removeFromSuperview] ;
	[self addSubview:aMouse] ;
	[[aMouse rootLayer] setPosition:mouseLocation] ;
}



- (void) toggleFullScreen {
	if ([self isInFullScreenMode]) {
		[self exitFullScreenModeWithOptions:nil] ;
		//[NSCursor unhide] ;
	} else {
		[self enterFullScreenMode:[[NSScreen screens] objectAtIndex:0] withOptions:nil] ;
		//[NSCursor hide] ;
	}
}

- (void) populateConfiguration {
	
	NSString *configPath = [[NSBundle mainBundle] pathForResource:@"JigSawKioskConfig" ofType:@"plist"];
	NSDictionary *dictionary = [[NSDictionary dictionaryWithContentsOfFile:configPath] retain];
	
	NSNumber *worker ;
	
	worker = [dictionary objectForKey:@"kUseDIVA"] ;
	kUseDIVA = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kFullScreen"] ;
	kFullScreen = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kRotate"] ;
	kRotate = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kDefaultMode"] ;
	kDefaultMode = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kFeedbackMode"] ;
	kFeedbackMode = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kIntroMode"] ;
	kIntroMode = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kMovieMode"] ;
	kMovieMode = (int) [worker integerValue] ;
	
	
	
	worker = [dictionary objectForKey:@"kRecordTime"] ;
	kRecordTime = (float) [worker floatValue] ;
	worker = [dictionary objectForKey:@"kUseInactivityTimer"] ;
	kUseInactivityTimer = (int) [worker integerValue] ;
	worker = [dictionary objectForKey:@"kInactivityDuration"] ;
	kInactivityDuration = (float) [worker floatValue] ;
	
	// Paths
	kGraphicsPath = [dictionary objectForKey:@"kGraphicsPath"] ;
	kMoviePath = [dictionary objectForKey:@"kMoviePath"] ;
	
	
	// grahpics
	kPlayBackBackgroundImage = [dictionary objectForKey:@"kPlayBackBackgroundImage"] ;
	kFeedBackBackgroundImage = [dictionary objectForKey:@"kFeedBackBackgroundImage"] ;
	kMouseImage = [dictionary objectForKey:@"kMouseImage"] ;
	kHotkeysImage = [dictionary objectForKey:@"kHotkeysImage"] ;
	kWatchSelectedImage = [dictionary objectForKey:@"kWatchSelectedImage"] ;
	kRecordGreenImage = [dictionary objectForKey:@"kRecordGreenImage"] ;
	kWatchUnselectedImage = [dictionary objectForKey:@"kWatchUnselectedImage"] ;
	kRecordRedImage = [dictionary objectForKey:@"kRecordRedImage"] ;
	kMovieRecordPath = [dictionary objectForKey:@"kMovieRecordPath"] ;
	
	// Movies
	worker = [dictionary objectForKey:@"kNumberOfMovies"] ;
	kNumberOfMovies = (float) [worker floatValue] ;
	
	kDefaultMovieName = [dictionary objectForKey:@"kDefaultMovieName"] ;
	kIntroMovieName = [dictionary objectForKey:@"kIntroMovieName"] ;
	
	kPreview1MovieName = [dictionary objectForKey:@"kPreview1MovieName"] ;
	kPreview2MovieName = [dictionary objectForKey:@"kPreview2MovieName"] ;
	kPreview3MovieName = [dictionary objectForKey:@"kPreview3MovieName"] ;
	kPreview4MovieName = [dictionary objectForKey:@"kPreview4MovieName"] ;
	kPreview5MovieName = [dictionary objectForKey:@"kPreview5MovieName"] ;
	kPreview6MovieName = [dictionary objectForKey:@"kPreview6MovieName"] ;
	kPreview7MovieName = [dictionary objectForKey:@"kPreview7MovieName"] ;
	kPreview8MovieName = [dictionary objectForKey:@"kPreview8MovieName"] ;
	kPreview9MovieName = [dictionary objectForKey:@"kPreview9MovieName"] ;
	
	kMovie1Name = [dictionary objectForKey:@"kMovie1Name"] ;
	kMovie2Name = [dictionary objectForKey:@"kMovie2Name"] ;
	kMovie3Name = [dictionary objectForKey:@"kMovie3Name"] ;
	kMovie4Name = [dictionary objectForKey:@"kMovie4Name"] ;
	kMovie5Name = [dictionary objectForKey:@"kMovie5Name"] ;
	kMovie6Name = [dictionary objectForKey:@"kMovie6Name"] ;
	kMovie7Name = [dictionary objectForKey:@"kMovie7Name"] ;
	kMovie8Name = [dictionary objectForKey:@"kMovie8Name"] ;
	kMovie9Name = [dictionary objectForKey:@"kMovie9Name"] ;
	
	worker = [dictionary objectForKey:@"kPreviewStopOpacity"] ;
	kPreviewStopOpacity = (float) [worker floatValue] ;
	
	// DIVA
	worker = [dictionary objectForKey:@"kDIVAtimeout"] ;
	kDIVAtimeout = (float) [worker floatValue] ;
	
	kDIVAip = [dictionary objectForKey:@"kDIVAip"] ;
	kDIVAport = [dictionary objectForKey:@"kDIVAport"] ;
	kDIVAusername = [dictionary objectForKey:@"kDIVAusername"] ;
	kDIVApassword = [dictionary objectForKey:@"kDIVApassword"] ;
	kDIVApresent = [dictionary objectForKey:@"kDIVApresent"] ;
	kDIVAabsent = [dictionary objectForKey:@"kDIVAabsent"] ;
	
	// Arduino
	worker = [dictionary objectForKey:@"kUseArduino"] ;
	kUseArduino = (int) [worker integerValue] ;
	kArduinoPort = [dictionary objectForKey:@"kArduinoPort"] ;
	worker = [dictionary objectForKey:@"kArduinoBaudRate"] ;
	kArduinoBaudRate = (int) [worker integerValue] ;
	
	// Email
	kEmailSMTP = [dictionary objectForKey:@"kEmailSMTP"] ;
	worker = [dictionary objectForKey:@"kEmailPort"] ;
	kEmailPort = (int) [worker floatValue] ;
	kEmailFromAddress = [dictionary objectForKey:@"kEmailFromAddress"] ;
	kEmailFromName = [dictionary objectForKey:@"kEmailFromName"] ;;
	kEmailFromPassword = [dictionary objectForKey:@"kEmailFromPassword"] ;
	kEmailFeedbackEmailSubject = [dictionary objectForKey:@"kEmailFeedbackEmailSubject"] ;
	kEmailFeedbackEmailHTMLFilepath = [dictionary objectForKey:@"kEmailFeedbackEmailHTMLFilepath"] ;
	kEmailFeedbackEmailHTMLImageDir = [dictionary objectForKey:@"kEmailFeedbackEmailHTMLImageDir"] ;
	kEmailFeedbackEmailTxtFilepath = [dictionary objectForKey:@"kEmailFeedbackEmailTxtFilepath"] ;
	kEmailDefaultMessage = [dictionary objectForKey:@"kEmailDefaultMessage"] ;
	kStartupEmailToAddress = [dictionary objectForKey:@"kStartupEmailToAddress"] ;
	kStartupEmailSubject = [dictionary objectForKey:@"kStartupEmailSubject"] ;
	kStartupEmailMessage = [dictionary objectForKey:@"kStartupEmailMessage"] ;
	
}

@end
